<?php
/**
 * <b>RUBIK IT Solution & Development ltd.</b>
 *
 * PROJECT		: Rubik Ultimate Framework
 * @version 	: 1.1
 * COPYRIGHT    : 2008
 * ------------------------------------------------------
 * 
 * Created on	:  Jun 16, 2008
 * 
 */

// no direct access
defined ( '_FW_EXEC' ) or die ( 'Restricted access' );
RCoreImporter::cls( "helper.RFileFolderHelper" );
class Language {
	var $_strings = array ();
	
	function Language($langFolder, $lang = null) {
		$this->_strings = array ();
		
		if ($lang == null) {
			$this->_lang = $this->_default;
		} else {
			$this->_lang = $lang;
		}
		$this->loadFromFolder ( $langFolder, $lang );
	}
	
	/**
	 * Translate function, mimics the php gettext (alias _) function
	 *
	 * @access	public
	 * @param	string		$string 	The string to translate
	 * @return	string	The translation of the string
	 * 
	 */
	function _($string) {
		//$key = str_replace( ' ', '_', strtoupper( trim( $string ) ) );echo '<br>'.$key;
		$key = strtoupper ( $string );
		
		if (isset ( $this->_strings [$key] )) {
			$string = $this->_strings [$key];
		}
		
		return $string;
	}
	/**
	 * Parse an .ini string, based on phpDocumentor phpDocumentor_parse_ini_file function
	 *
	 * @access public
	 * @param mixed The INI string or array of lines
	 * @param boolean add an associative index for each section [in brackets]
	 * @return object Data Object
	 */
	function stringToObject($data, $process_sections = false) {
		static $inistocache;
		
		if (! isset ( $inistocache )) {
			$inistocache = array ();
		}
		
		if (is_string ( $data )) {
			$lines = explode ( "\n", $data );
			$hash = md5 ( $data );
		} else {
			if (is_array ( $data )) {
				$lines = $data;
			} else {
				$lines = array ();
			}
			$hash = md5 ( implode ( "\n", $lines ) );
		}
		
		if (array_key_exists ( $hash, $inistocache )) {
			return $inistocache [$hash];
		}
		
		$obj = new stdClass ( );
		
		$sec_name = '';
		$unparsed = 0;
		if (! $lines) {
			return $obj;
		}
		
		foreach ( $lines as $line ) {
			// ignore comments
			if ($line && $line {0} == ';') {
				continue;
			}
			
			$line = trim ( $line );
			
			if ($line == '') {
				continue;
			}
			
			$lineLen = strlen ( $line );
			if ($line && $line {0} == '[' && $line {$lineLen - 1} == ']') {
				$sec_name = substr ( $line, 1, $lineLen - 2 );
				if ($process_sections) {
					$obj->$sec_name = new stdClass ( );
				}
			} else {
				if ($pos = strpos ( $line, '=' )) {
					$property = trim ( substr ( $line, 0, $pos ) );
					
					// property is assumed to be ascii
					if ($property && $property {0} == '"') {
						$propLen = strlen ( $property );
						if ($property {$propLen - 1} == '"') {
							$property = stripcslashes ( substr ( $property, 1, $propLen - 2 ) );
						}
					}
					// AJE: 2006-11-06 Fixes problem where you want leading spaces
					// for some parameters, eg, class suffix
					// $value = trim(substr($line, $pos +1));
					$value = substr ( $line, $pos + 1 );
					
					if (strpos ( $value, '|' ) !== false && preg_match ( '#(?<!\\\)\|#', $value )) {
						$newlines = explode ( '\n', $value );
						$values = array ();
						foreach ( $newlines as $newlinekey => $newline ) {
							
							// Explode the value if it is serialized as an arry of value1|value2|value3
							$parts = preg_split ( '/(?<!\\\)\|/', $newline );
							$array = (strcmp ( $parts [0], $newline ) === 0) ? false : true;
							$parts = str_replace ( '\|', '|', $parts );
							
							foreach ( $parts as $key => $value ) {
								if ($value == 'false') {
									$value = false;
								} else if ($value == 'true') {
									$value = true;
								} else if ($value && $value {0} == '"') {
									$valueLen = strlen ( $value );
									if ($value {$valueLen - 1} == '"') {
										$value = stripcslashes ( substr ( $value, 1, $valueLen - 2 ) );
									}
								}
								if (! isset ( $values [$newlinekey] ))
									$values [$newlinekey] = array ();
								$values [$newlinekey] [] = str_replace ( '\n', "\n", $value );
							}
							
							if (! $array) {
								$values [$newlinekey] = $values [$newlinekey] [0];
							}
						}
						
						if ($process_sections) {
							if ($sec_name != '') {
								$obj->$sec_name->$property = $values [$newlinekey];
							} else {
								$obj->$property = $values [$newlinekey];
							}
						} else {
							$obj->$property = $values [$newlinekey];
						}
					} else {
						//unescape the \|
						$value = str_replace ( '\|', '|', $value );
						
						if ($value == 'false') {
							$value = false;
						} else if ($value == 'true') {
							$value = true;
						} else if ($value && $value {0} == '"') {
							$valueLen = strlen ( $value );
							if ($value {$valueLen - 1} == '"') {
								$value = stripcslashes ( substr ( $value, 1, $valueLen - 2 ) );
							}
						}
						
						if ($process_sections) {
							$value = str_replace ( '\n', "\n", $value );
							if ($sec_name != '') {
								$obj->$sec_name->$property = $value;
							} else {
								$obj->$property = $value;
							}
						} else {
							$obj->$property = str_replace ( '\n', "\n", $value );
						}
					}
				} else {
					if ($line && $line {0} == ';') {
						continue;
					}
					if ($process_sections) {
						$property = '__invalid' . $unparsed ++ . '__';
						if ($process_sections) {
							if ($sec_name != '') {
								$obj->$sec_name->$property = trim ( $line );
							} else {
								$obj->$property = trim ( $line );
							}
						} else {
							$obj->$property = trim ( $line );
						}
					}
				}
			}
		}
		
		$inistocache [$hash] = $obj;
		return $obj;
	}
	
	/**
	 * Loads a Folder language file and appends the results to the existing strings
	 *
	 * @access	public
	 * @param	string	$folder		Folder of Language files
	 * @param	string	$lang		The language to load, default null for the current language
	 * 
	 */
	function loadFromFolder($folder, $lang = null) {
		if (!file_exists($folder)) {
			return null;
		}
		if (! $lang) {
			$lang = $this->_lang;
		}
		$result = false;
		$files = RFileFolderHelper::files ( $folder, 'ini', false, true );
		foreach ( $files as $filename ) {
			$result = $this->_load ( $filename );
		}
		
		return $result;
	
	}
	
	/**
	 * Loads a single language file and appends the results to the existing strings
	 *
	 * @access	public
	 * @param	string	$file		Path of language file
	 * 
	 */
	function loadINI($file) {
		$result = false;
		
		// Load the language file
		if (file_exists ( $file )) {
			$result = $this->_load ( $file );
		} else {
			RError::raiseWarning ( 120, "Language file: <b>'$file'</b> wasn't loaded." );
		}
		return $result;
	
	}
	
	/**
	 * Loads a language file
	 *
	 * This method will not note the successful loading of a file - use load() instead
	 *
	 * @access	private
	 * @param	string The name of the file
	 * @return	boolean True if new strings have been added to the language
	 * 
	 */
	function _load($filename) {
		$result = false;
		
		if ($content = @file_get_contents ( $filename )) {
			$Strings = $this->stringToObject ( $content );
			$newStrings = $this->toArray ( $Strings );
			if (is_array ( $newStrings )) {
				$this->_strings = array_merge ( $this->_strings, $newStrings );
				$result = true;
			}
		}
		
		return $result;
	}
	
	/**
	 * Transforms a Object to an array
	 *
	 */
	function toArray($Ob = null) {
		$array = array ();
		if ($Ob != null) {
			foreach ( get_object_vars ( $Ob ) as $k => $v ) {
				$array [$k] = $v;
			}
		}
		return $array;
	}

	/**
	 * Get the language array inside language object
	 *
	 * @return array
	 */
	function getLanguageArray() {
		return $this->_strings;
	}
}

?>